package com.example.shiro_demo.server.impl;

import com.example.shiro_demo.entity.Authority;
import com.example.shiro_demo.mapper.AuthorityMapper;
import com.example.shiro_demo.server.ShiroService;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 权限操作
 * @Author: wuzs
 * @Date: 2019/10/14 16:56
 */
@Service
public class ShiroServiceImpl implements ShiroService {
    @Autowired
    private AuthorityMapper authorityMapper;
    /**
     * 初始化权限
     * @return
     */
    @Override
    public Map<String, String> loadFilterChainDefinitions() {
        //数据库中获取权限信息
        List<Authority> authorities = authorityMapper.findAuthorities();
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        if (authorities.size() > 0){
            String uris;
            String[] uriArr;
            for (Authority authority : authorities) {
                if (StringUtils.isEmpty(authority.getPermission())){
                    continue;
                }
                uris = authority.getUri();
                //uri字段支持”,“隔开的多uri
                uriArr = uris.split(",");
                for (String s : uriArr) {
                    filterChainDefinitionMap.put(s, authority.getPermission());
                }
            }
        }
        filterChainDefinitionMap.put("/user/login", "anon");
        //退出
        filterChainDefinitionMap.put("/user/logout", "anon");
        //拦截所有请求
        filterChainDefinitionMap.put("/**", "authc");
        return filterChainDefinitionMap;
    }

    /**
     * 更新权限
     * @param shiroFilterFactoryBean
     */
    @Override
    public void updatePermission(ShiroFilterFactoryBean shiroFilterFactoryBean) {
        synchronized (this){
            AbstractShiroFilter shiroFilter;
            try {
                shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
            } catch (Exception e) {
                throw new RuntimeException("获取ShiroFilter出错");
            }
            PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
            DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
            //清空
            manager.getFilterChains().clear();
            shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
            shiroFilterFactoryBean.setFilterChainDefinitionMap(loadFilterChainDefinitions());
            //重新加载chain
            Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
            for (Map.Entry<String, String> entry : chains.entrySet()){
                String url = entry.getKey();
                String chainDefinition = entry.getValue().trim().replace(" ", "");
                manager.createChain(url, chainDefinition);
            }
        }
    }
}
